package com.how2java.tmall.web;

import com.how2java.tmall.comparator.*;
import com.how2java.tmall.pojo.*;
import com.how2java.tmall.service.*;
import com.how2java.tmall.util.Result;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class ForeRESTController {

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserService userService;
    @Autowired
    private ProductImageService productImageService;
    @Autowired
    private PropertyValueService propertyValueService;
    @Autowired
    private ReviewService reviewService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private OrderService orderService;


    @GetMapping("/forehome")
    public Object home(){
        List<Category> cs = categoryService.list();
        productService.fill(cs);
        productService.fillByRow(cs);
        categoryService.removeCategoryFromProduct(cs);
        return cs;
    }

    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping("/foreregister")
    public Object register(@RequestBody User user){
        String name= user.getName();
        String password = user.getPassword();
        name = HtmlUtils.htmlEscape(name);
        user.setName(name);
        boolean isExist = userService.isExist(name);

        if(isExist){
            String message = "该用户名已经被使用，请重新输入！";
            return Result.fail(message);
        }
        String salt = new SecureRandomNumberGenerator().nextBytes().toString();
        int time =2;
        String algorithmName = "md5";

        String encodedPassword = new SimpleHash(algorithmName,password,salt,time).toString();
        user.setPassword(encodedPassword);
        user.setSalt(salt);
        userService.add(user);

        return Result.success();
    }

    /**
     * 登录验证
     * @param userParam
     * @param session
     * @return
     */
    @PostMapping("/forelogin")
    public Object login(@RequestBody User userParam, HttpSession session){
        String name= userParam.getName();
        name = HtmlUtils.htmlEscape(name);

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(name,userParam.getPassword());
        try{
            subject.login(token);
            User user = userService.getUserByName(name);
            session.setAttribute("user",user);
            return Result.success();
        }catch (AuthenticationException e){
            String message = "账号密码错误，请重新输入！";
            return Result.fail(message);
        }

    }

    /**
     * 产品详情页
     * @param pid
     * @return
     */
    @GetMapping("/foreproduct/{pid}")
    public Object product(@PathVariable("pid") int pid){
        Product product = productService.get(pid);

        List<ProductImage> productSingleImages = productImageService.listSingleProductImages(product);
        List<ProductImage> productDetailImages = productImageService.listDetailProductImages(product);

        product.setProductSingleImages(productSingleImages);
        product.setProductDetailImages(productDetailImages);

        List<PropertyValue> pvs = propertyValueService.list(product);
        List<Review> reviews = reviewService.list(product);
        productService.setSaleAndReviewNumber(product);
        productImageService.setFirstProductImage(product);

        Map<String,Object> map = new HashMap<>();
        map.put("product",product);
        map.put("pvs",pvs);
        map.put("reviews",reviews);

        return Result.success(map);

    }

    /**
     * 检验是否登录
     * @param
     * @return
     */
    @GetMapping("/forecheckLogin")
    public Object checkLogin(){
        Subject subject = SecurityUtils.getSubject();
        if(subject.isAuthenticated()){
            return Result.success();
        }else{
            return Result.fail("未登录");
        }
    }

    /**
     * 分类页
     * @param cid
     * @param sort
     * @return
     */
    @GetMapping("forecategory/{cid}")
    public Object category(@PathVariable("cid") int cid,String sort){
        Category category = categoryService.get(cid);
        productService.fill(category);
        productService.setSaleAndReviewNumber(category.getProductList());
        categoryService.removeCategoryFromProduct(category);

        if(null!=sort){
            switch (sort){
                case "review":
                    Collections.sort(category.getProductList(),new ProductReviewComparator());
                    break;
                case "date":
                    Collections.sort(category.getProductList(),new ProductDateComparator());
                    break;
                case "saleCount":
                    Collections.sort(category.getProductList(),new ProductSaleCountComparator());
                    break;
                case "price":
                    Collections.sort(category.getProductList(),new ProductPriceComparator());
                    break;
                case "all":
                    Collections.sort(category.getProductList(),new ProductAllComparator());
                    break;
            }
        }
        return category;
    }

    /**
     * 根据产品名称进行搜索
     * @param keyword
     * @return
     */
    @PostMapping("foresearch")
    public Object search(String keyword){
        if(null == keyword){
            keyword="";
        }
        List<Product> ps = productService.search(keyword,0,20);
        productImageService.setFirstProductImages(ps);
        productService.setSaleAndReviewNumber(ps);
        return ps;
    }


    @GetMapping("/forebuyone")
    public Object buyone(int pid,int num ,HttpSession session){
        return buyoneAndAddCart(pid,num,session);
    }

    //购买
    private int buyoneAndAddCart(int pid,int num ,HttpSession session){
        Product product = productService.get(pid);
        int  oiid = 0;

        User user = (User)session.getAttribute("user");
        boolean found = false;
        List<OrderItem> ois = orderItemService.listByUser(user);
        for(OrderItem oi : ois){
            //判断购物车当中是否有该商品
            if(oi.getProduct().getId() == product.getId()){
                //购物车中有该商品
                oi.setNumber(oi.getNumber()+num);
                orderItemService.update(oi);
                found = true;
                oiid = oi.getId();
                break;
            }
        }
        if(!found){
            //购物车中没有该商品，就需要新生成订单项
            OrderItem oi = new OrderItem();
            oi.setUser(user);
            oi.setProduct(product);
            oi.setNumber(num);
            orderItemService.add(oi);
            oiid = oi.getId();
        }
        return oiid;
    }

    @GetMapping("/forebuy")
    public Object buy(String[] oiid, HttpSession session){
        List<OrderItem> orderItems = new ArrayList<>();
        float total = 0;

        for(String strid:oiid){
            int id = Integer.parseInt(strid);
            OrderItem oi = orderItemService.get(id);
            total +=oi.getProduct().getPromotePrice()*oi.getNumber();
            orderItems.add(oi);
        }

        productImageService.setFirstProductImagesOnorderItems(orderItems);

        session.setAttribute("ois",orderItems);

        Map<String,Object> map = new HashMap<>();
        map.put("orderItems",orderItems);
        map.put("total",total);
        return Result.success(map);
    }

    //添加到购物车
    @GetMapping("/foreaddCart")
    public Object addCart(int pid,int num,HttpSession session){
        buyoneAndAddCart(pid,num,session);
        return Result.success();
    }

    //购物车页面初始化
    @GetMapping("/forecart")
    public Object cart(HttpSession session){
        User user = (User) session.getAttribute("user");
        List<OrderItem> ois = orderItemService.listByUser(user);
        productImageService.setFirstProductImagesOnorderItems(ois);
        return ois;
    }

    //修改购物车中商品的数量
    @GetMapping("/forechangeOrdetItem")
    public Object changeOrderItem(HttpSession session,int pid,int num){
        User user = (User)session.getAttribute("user");

        if(null==user){
            return Result.fail("未登录");
        }

        List<OrderItem> ois = orderItemService.listByUser(user);
        for(OrderItem oi : ois){
            if(oi.getProduct().getId() == pid){
                oi.setNumber(num);
                orderItemService.update(oi);
                break;
            }
        }
        return Result.success();
    }
    //删除购物车中的商品
    @GetMapping("/foredeleteOrderItem")
    public Object deleteOrderItem(HttpSession session,int oiid){
        User user = (User)session.getAttribute("user");
        if(null == user){
            return Result.fail("未登录");
        }
        orderItemService.delete(oiid);
        return Result.success();
    }

    //生成订单
    @PostMapping("/forecreateOrder")
    public Object createOrder(@RequestBody Order order,HttpSession session){
        User user =(User) session.getAttribute("user");
        if(null == user){
            return Result.fail("未登录");
        }
        String orderCode = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())+ RandomUtils.nextInt(10000);
        order.setOrderCode(orderCode);
        order.setCreateDate(new Date());
        order.setUser(user);
        order.setStatus(OrderService.waitPay);
        List<OrderItem> ois = (List<OrderItem>)session.getAttribute("ois");
        float total = orderService.add(order,ois);

        Map<String,Object> map = new HashMap<>();
        map.put("oid",order.getId());
        map.put("total",total);

        return Result.success(map);
    }

    //支付
    @GetMapping("/forepayed")
    public Object payed(int oid){
        Order order = orderService.get(oid);
        order.setStatus(OrderService.waitDelivery);
        order.setPayDate(new Date());
        orderService.update(order);
        return order;
    }

    //查看没有删除的我的订单
    @GetMapping("/forebought")
    public Object bought(HttpSession session){
        User user = (User)session.getAttribute("user");
        if(null == user){
            return Result.fail("未登录");
        }
        List<Order> os = orderService.listByUserWithoutDelete(user);
        orderItemService.fill(os);
        orderService.removeOrderFromOrderItem(os);
        return os;
    }

    //确认收货页面初始化
    @GetMapping("/foreconfirmPay")
    public Object confirmPay(int oid){
        Order o = orderService.get(oid);
        orderItemService.fill(o);
        orderService.cacl(o);
        orderService.removeOrderFromOrderItem(o);
        return o;
    }

    //确认收货结算页面
    @GetMapping("/foreorderConfirmed")
    public Object orderConfirmed(int oid){
        Order o = orderService.get(oid);
        o.setStatus(OrderService.waitReview);
        o.setConfirmDate(new Date());
        orderService.update(o);
        return Result.success();
    }

    //删除订单
    @PutMapping("/foredeleteOrder")
    public Object deleteOrder(int oid){
        Order o = orderService.get(oid);
        o.setStatus(OrderService.delete);
        orderService.update(o);
        return Result.success();
    }

    //评价页面
    @GetMapping("/forereview")
    public Object review(int oid){
        Order o = orderService.get(oid);
        orderItemService.fill(o);
        orderService.removeOrderFromOrderItem(o);
        Product p = o.getOrderItems().get(0).getProduct();
        List<Review> reviews = reviewService.list(p);
        productService.setSaleAndReviewNumber(p);
        Map<String,Object> map = new HashMap<>();
        map.put("p",p);
        map.put("o",o);
        map.put("reviews",reviews);

        return Result.success(map);
    }

    @PostMapping("/foredoreview")
    public Object doreivew(HttpSession session,int oid,int pid,String content){
        Order o = orderService.get(oid);
        o.setStatus(OrderService.finish);
        orderService.update(o);

        Product p = productService.get(pid);
        content = HtmlUtils.htmlEscape(content);

        User user = (User)session.getAttribute("user");
        Review review = new Review();
        review.setContent(content);
        review.setProduct(p);
        review.setCreateDate(new Date());
        review.setUser(user);
        reviewService.add(review);

        return Result.success();

    }





}

